package com.qcby.chatservice.web.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.ImmutableMap;
import com.qcby.chatservice.web.domain.CaLoginUser;
import com.qcby.chatservice.web.domain.LoginUserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * sso身份验证拦截器
 *
 * @author cong.zhen
 * @date 2023/01/29
 */
@Slf4j
public class SsoAuthenticationInterceptor implements HandlerInterceptor {
    public static final String TOKEN_HEADER = "token";
    @Value("${sso.url}")
    private String ssoUrl;


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!checkBefore(request, response, handler)) {
            response.setStatus(HttpStatus.HTTP_FORBIDDEN);
        }
        return true;
    }

    public boolean checkBefore(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1. 获取当前用户的token，可能为null
        String token = request.getHeader(TOKEN_HEADER);
        // 2. 如果token不为空，则先判断是否登录过期了，过期了就直接打回，不过期不做处理
        try{
            if (StrUtil.isNotBlank(token)) {
                String URL = ssoUrl + "/hongyan-sso/app/logincheck";
                // 请求sso服务探测sso
                String body = HttpUtil.post(URL, JSONUtil.toJsonStr(ImmutableMap.of("caToken", StrUtil.trimToEmpty(token))));
                // 获取返回结果的message
                JSONObject jsonObject = new JSONObject();
                if (StrUtil.isNotBlank(body)) {
                    jsonObject = JSONUtil.parseObj(body);
                }

                // 从body中获取data
                JSONObject data = jsonObject.getJSONObject("data");
                CaLoginUser caLoginUser = JSONUtil.toBean(data.getJSONObject("caLoginUser"), CaLoginUser.class);
                if(caLoginUser == null){
                    return false;
                }

                LoginUserHolder.set(caLoginUser);
                return true;
            }
        }catch (Exception e){
            log.error("", e);
        }

        return false;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        try {
            LoginUserHolder.remove();
        } catch (Exception e) {
            // 清空失败
            log.error("清空threadLocal失败！", e);
        }
    }
}
